home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d1 / dostech.arc / CHAP10 < prev    next >
Text File  |  1989-02-04  |  71KB  |  1,384 lines

  1.  
  2. CHAPTER 10
  3.  
  4.  Programming Technical Reference - IBM
  5.  Copyright 1988, Dave Williams
  6.  
  7.            LOTUS-INTEL-MICROSOFT  EXPANDED MEMORY SPECIFICATION
  8.  
  9. The Expanded Memory Manager ............................................ 10-
  10.         History ........................................................ 10-
  11.         Page Frames .................................................... 10-
  12. Expanded Memory Services ............................................... 10-
  13. AST/Quadram/Ashton-Tate Enhanced EMM ................................... 10-
  14.         Calling the Manager ............................................ 10-
  15.         Common EMS Functions (hex calls)
  16.                  1 (40h) Get Manager Status ............................ 10-
  17.                  2 (41h) Get Page Frame Segment ........................ 10-
  18.                  3 (42h) Get Number of Pages ........................... 10-
  19.                  4 (43h) Get Handle and Allocate Memory ................ 10-
  20.                  5 (44h) Map Memory .................................... 10-
  21.                  6 (45h) Release Handle and Memory ..................... 10-
  22.                  7 (46h) Get EMM Version ............................... 10-
  23.                  8 (47h) Save Mapping Context .......................... 10-
  24.                  9 (48h) Restore Mapping Context ....................... 10-
  25.                 10 (49h) Reserved ...................................... 10-
  26.                 11 (4Ah) Reserved ...................................... 10-
  27.                 12 (4Bh) Get Number of EMM Handles ..................... 10-
  28.                 12 (4Ch) Get Pages Owned By Handle ..................... 10-
  29.                 14 (4Dh) Get Pages for All Handles ..................... 10-
  30.                 15 (4Eh) Get Or Set Page Map ........................... 10-
  31.        new LIM 4.0 specification:
  32.                 16 (4Fh) Get/Set Partial Page Map ...................... 10-
  33.                 17 (50h) Map/Unmap Multiple Pages ...................... 10-
  34.                 18 (51h) Reallocate Pages .............................. 10-
  35.                 19 (52h) Handle Attribute Functions .................... 10-
  36.                 20 (53h) Get Handle Name ............................... 10-
  37.                 21 (54h) Get Handle Directory .......................... 10-
  38.                 22 (55h) Alter Page Map & Jump ......................... 10-
  39.                 23 (56h) Alter Page Map & Call ......................... 10-
  40.                 24 (57h) Move Memory Region ............................ 10-
  41.                 25 (58h) Get Mappable Physical Address Array ........... 10-
  42.                 26 (59h) Get Expanded Memory Hardware .................. 10-
  43.                 27 (5Ah) Allocate Raw Pages ............................ 10-
  44.                 28 (5Bh) Get Alternate Map Register Set ................ 10-
  45.                 29 (5Ch) Prepare Expanded Memory Hardware .............. 10-
  46.                 30 (5Dh) Enable OS/E Function Set ...................... 10-
  47.                 31 (5Eh) Unknown ....................................... 10-
  48.                 32 (5Fh) Unknown ....................................... 10-
  49.                 33 (60h) Unknown ....................................... 10-
  50.                 34 (61h) AST Generic Accelerator Card Support .......... 10-
  51. Expanded Memory Manager Error Codes .................................... 10-
  52.  
  53.  
  54.  
  55. THE EXPANDED MEMORY MANAGER
  56.  
  57. History
  58.  
  59.  The Lotus/Intel/Microsoft Expanded Memory Manager was originally a Lotus and
  60. Intel project and was announced as version 3.0 in the second quarter of 1985
  61. primarily as a means of running larger Lotus worksheets by transparently
  62. paging unused sections to bank-switched memory. Shortly afterward Microsoft
  63. announced support of the standard and version 3.2 was subsequently released
  64. with support for Microsoft Windows. LIM 3.2 supported up to 8 megabytes of
  65. paged memory. The LIM 4.0 supports up to 32 megabytes of paged memory.
  66.  
  67.  
  68.  
  69. AST/QUADRAM/ASHTON-TATE ENHANCED EXPANDED MEMORY SPECIFICATION
  70.  
  71.  The AQA EEMS maintains upward compatibility with the LIM, but is a superset
  72. of functions.
  73.  
  74.  The AQA EEMS permits its pages to be scattered throughout the unused portion
  75. of the machine's address space.
  76.  
  77. On August 19, 1987, the new version of the Expanded Memory Specification (EMS)
  78. was announced by Lotus, Intel and Microsoft. This new version of the
  79. specification includes many features of the Enhanced Expanded Memory
  80. Specification (EEMS) originally developed by AST Reserach, Quadram and Ashton-
  81. Tate, although the three original sponsoring companies elected not to make the
  82. new specification upward compatible with EEMS. AST Research says that they will
  83. endorse EMS 4.0 without reservation.
  84.  
  85.  The definitive document for the LIM-EMS is Intel part number 300275-004,
  86. August, 1987.
  87.  
  88.                                                        32M ┌──────────────┐
  89.                                                           /│              │
  90.                                                            │              │
  91.                                                      /     │              │
  92.                                                            │              │
  93.                                                 /          │              │
  94.                                                            │              │
  95.                                            /               │              │
  96.                                                            │   Expanded   │
  97.                                       /                    │    Memory    │
  98.           1024K ┌──────────────┐                           │              │
  99.                 │ / / / / / /  │  /                        │              │
  100.            960K ├──────────────┤                           │              │
  101.                 │  Page Frame  │                           │              │
  102.                 │              │                           │              │
  103.                 │ 12 16K-Byte  │                           │              │
  104.                 │   Physical   │                           │              │
  105.                 │    Pages     │                           │              │
  106.            768K ├──────────────┤                           │ Divided into │
  107.                 │ / / / / / /  │ \                         │   logical    │
  108.            640K ├──────────────┤                           │    pages     │
  109.                 │              │   \                       │              │
  110.                 │              │                           │              │
  111.                 │              │     \                     │              │
  112.                 │              │                           │              │
  113.                 │ 24 16K-Byte  │       \                   │              │
  114.                 │   Physical   │                           │              │
  115.                 │    Pages*    │         \                 │              │
  116.                 │              │                           │              │
  117.                 │              │           \               │              │
  118.                 │              │                           │              │
  119.                 │              │             \             │              │
  120.            256K ├──────────────┤                           │              │
  121.                 │              │               \           │              │
  122.                 │ / / / / / /  │                           │              │
  123.                 │              │                 \         │              │
  124.                 │ / / / / / /  │                           │              │
  125.                 │              │                   \       │              │
  126.                 │ / / / / / /  │                           │              │
  127.                 │              │                     \     │              │
  128.               0 └──────────────┘                           │              │
  129.                                                        \   │              │
  130.                                                            │              │
  131.                                                          \ │              │
  132.                                                          0 └──────────────┘
  133.  
  134.  
  135.  The page frame is located above the 640k system RAM area, anywhere from
  136. 0A000h to 0FFFFh. This area is used by the video adapters, network cards, and
  137. add-on ROMs (as in hard disk controllers). The page frames are mapped around
  138. areas that are in use.
  139.  
  140.  
  141.  
  142.                  WRITING PROGRAMS THAT USE EXPANDED MEMORY
  143.  
  144.  In order to use expanded memory, applications must perform these steps in the
  145. following order:
  146.  
  147. 1. Determine if EMM is installed.
  148. 2. Determine if enough expanded memory pages exist for your application.
  149.    (Function 3)
  150. 3. Allocate expanded memory pages. (Function 4 or 18)
  151. 4. Get the page frame base address. (Function 2)
  152. 5. Map in expanded memory pages. (Function 5 or 17)
  153. 6. Read/write/execute data in expanded memory, just as if it were conventional
  154.    memory.
  155. 7. Return expanded memory pages to expanded memory pool before exiting. Function
  156.    6 or 18)
  157.  
  158.  
  159. Programming Guidelines
  160.  
  161.  The following section contains guidelines for programmers writing applications
  162. that use EMM.
  163.  
  164. A) Do not put a program's stack in expanded memory.
  165.  
  166. B) Do not replace interrupt 67h. This is the interrupt vector the EMM uses.
  167.    Replacing interrupt 67h could result in disabling the Expanded Memory
  168.    Manager.
  169.  
  170. C) Do not map into conventional memory address space your application doesn't
  171.    own. Applications that use the EMM to swap into conventional memory space,
  172.    must first allocate this space from the operating system. If the operating
  173.    system is not aware that a region of memory it manages is in use, it will
  174.    think it is available. This could have disastrous results. EMM should not be
  175.    used to "allocate" conventional memory. DOS is the proper manager of
  176.    conventional memory space. EMM should only be used to swap data in
  177.    conventional memory space previously allocated from DOS.
  178.  
  179. D) Applications that plan on using data aliasing in expanded memory must check
  180.    for the presence of expanded memory hardware. Data aliasing occurs when
  181.    mapping one logical page into two or more mappable segments. This makes one
  182.    16K-byte expanded memory page appear to be in more than one 16K-byte memory
  183.    address space. Data aliasing is legal and sometimes useful for applications.
  184.     Software-only expanded memory emulators cannot perform data aliasing. A
  185.    simple way to distinguish software emulators from actual expanded memory
  186.    hardware is to attempt data aliasing and check the results. For example, map
  187.    one logical page into four physical pages. Write to physical page 0. Read
  188.    physical pages 1-3 to see if the data is there as well. If the data appears
  189.    in all four physical pages, then expanded memory hardware is installed in the
  190.    system, and data aliasing is supported.
  191.  
  192. E) Applications should always return expanded memory pages to the expanded
  193.    memory manager upon termination. These pages will be made available for other
  194.    applications. If unneeded pages are not returned to the expanded memory
  195.    manager, the system could run out of expanded memory pages or expanded
  196.    memory handles.
  197.  
  198. F) Terminate and stay resident programs (TSRs) should always save the state of
  199.    the map registers before changing them. Since TSRs may interrupt other
  200.    programs which may be using expanded memory, they must not change the state
  201.    of the page mapping registers without first saving them. Before exiting, TSRs
  202.    must restore the state of the map registers.
  203.     The following sections describe the three ways to save and restore the state
  204.    of the map registers.
  205.    1) Save Page Map and Restore Page Map (Functions 8 and 9). This is the
  206.       simplest of the three methods. The EMM saves the map register contents in
  207.       its own data structures -- the application does not need to provide extra
  208.       storage locations for the mapping context. The last mapping context to be
  209.       saved, under a particular handle, will be restored when a call to Restore
  210.       Page Map is issued with the same handle. This method is limited to one
  211.       mapping context for each handle and saves the context for only LIM
  212.       standard 64K-byte page frames.
  213.    2) Get/Set Page Map (Function 15). This method requires the application to
  214.       allocate space for the storage array. The EMM saves the mapping context in
  215.       an array whose address is passed to the EMM. When restoring the mapping
  216.       context with this method, an application passes the address of an array
  217.       which contains a previously stored mapping context. This method is
  218.       preferable if an application needs to do more than one save before a
  219.       restore. It provides a mechanism for switching between more than one
  220.       mapping context.
  221.    3) Get/Set Partial Page Map (Function 16). This method provides a way for
  222.       saving a partial mapping context. It should be used when the application
  223.       does not need to save the context of all mappable memory. This function
  224.       also requires that the storage array be part of the application's data.
  225.  
  226. G) All functions using pointers to data structures must have those data
  227.    structures in memory which will not be mapped out. Functions 22 and 23
  228.    (Alter Map & Call and Alter Map & Jump) are the only exceptions.
  229.  
  230.  
  231.  
  232. EMS 4.0 SPECIFICATIONS
  233.  
  234. Page Frames
  235.  
  236.  The bank switched memory chunks are referred to as "page frames". These frame
  237. consist of four 16K memory blocks mapped into some of the normally unused
  238. system ROM address area, 0C0000-0EFFFF. Each 16K page is independent of the
  239. other and they can map to discrete or overlapping areas of the 8 megabyte
  240. expanded memory address area. Most cards allow selection of addresses to prevent
  241. conflict with other cards, such as hard disk controllers and other expanded
  242. memory boards.
  243.  
  244.  
  245. Calling the Manager
  246.  
  247.  Applications programs communicate with the EMM device driver directly via user
  248. interrupt 67h. All communication between the application program and the driver
  249. bypasses DOS completely. To call the driver, register AH is loaded with the
  250. number of the EMM service requested; DX is loaded with the file handle; and
  251. interrupt 67h is called. ES:DI is used to pass the address of a buffer or array
  252. if needed.
  253.  On return AH contains 0 if the call was successful or an error code from 80h to
  254. 8Fh if unsuccessful.
  255.  
  256.  
  257.  
  258.           TESTING FOR THE PRESENCE OF THE EXPANDED MEMORY MANAGER
  259.  
  260.  Before an application program can use the Expanded Memory Manager, it must
  261. determine whether the manager is present. The two recommended methods are the
  262. "open handle" technique and the "get interrupt vector" technique.
  263.  
  264.  The majority of application programs can use either the "open handle" or the
  265. "get interrupt vector" method. However, if your program is a device driver or
  266. if it interrupts DOS during file system operations, you must use only the "get
  267. interrupt vector" method.
  268.  
  269.  Device drivers execute from within DOS and can't access the DOS file functions;
  270. programs that interrupt DOS during file operations have a similar restriction.
  271. During their interrupt processing procedures, they can't access the DOS file
  272. functions because another program may be using the system. Since the "get
  273. interrupt vector" method doesn't require the DOS file functions, you must use
  274. it for programs of this type.
  275.  
  276.  
  277.  The "Open Handle" Method
  278.  
  279.  Most application programs can use the DOS "Open Handle" method to test for
  280. the presence of the EMM. To use this method, follow these steps in order:
  281.  
  282. 1) Issue an "open handle" command (DOS function 3Dh) in "read only" access mode
  283.    (register AL = 0). This function requires your program to point to an ASCII
  284.    string which contains the path name of the file or device in which you're
  285.    interested (register set DS:DX contains the pointer). In this case the file
  286.    is actually the reserved name of the expanded memory manager.
  287.  
  288.    you should format the ASCII string as follows:
  289.  
  290.    ASCII_device_name  DB  'EMMXXXX0', 0
  291.  
  292.    The ASCII codes for the capital letters EMMXXXX0 are terminated by a byte
  293.    containing a value of zero.
  294.  
  295. 2) If DOS returns no error code, skip Steps 3 and 4 and go to Step 5. If DOS
  296.    returns a "Too many open files" error code, go to Step 3. If DOS returns a
  297.    "File/Path not found" error code, skip Step 3 and go to Step 4.
  298.  
  299. 3) If DOS returns a "Too many open files" (not enough handles) status code, your
  300.    program should invoke the "open file" command before it opens any other
  301.    files. This will guarantee that at least one file handle will be available to
  302.    perform the function without causing this error.
  303.     After the program performs the "open file" command, it should perform the
  304.    test described in Step 6 and close the "file handle" (DOS function 3Eh).
  305.    Don't keep the manager "open" after this status test is performed since
  306.    "manager" functions are not available through DOS. Go to Step 6.
  307.  
  308. 4) If DOS returns a "File/Path not found," the memory manager is not installed.
  309.    If your application requires the memory manager, the user will have to reboot
  310.    the system with a disk containing the memory manager and the appropriate
  311.    CONFIG.SYS file before proceeding.
  312.  
  313. 5) If DOS doesn't return an error status code you can assume that either a
  314.    device with the name EMMXXXX0 is resident in the system, or a file with this
  315.    name is on disk in the current disk drive. Go to Step 6.
  316.  
  317. 6) Issue an "I/O Control for Devices" command (DOS function 44h) with a "get
  318.    device information" command (register AL = 0). DOS function 44h determines
  319.    whether EMMXXXX0 is a device or a file.
  320.     You must use the file handle (register BX) which you obtained in Step 1 to
  321.    access the "EMM" device.
  322.    This function returns the "device information" in a word (register DX).
  323.    Go to Step 7.
  324.  
  325. 7. If DOS returns any error code, you should assume that the memory manager
  326.    device driver is not installed. If your application requires the memory
  327.    manager, the user will have to reboot the system with a disk containing the
  328.    memory manager and the appropriate CONFIG.SYS file before proceeding.
  329.  
  330. 8) If DOS didn't return an error status, test the contents of bit 7 (counting
  331.    from 0) of the "device information" word (register DX) the function
  332.    returned. Go to Step 9.
  333.  
  334. 9) If bit 7 of the "device information" word contains a zero, then EMMXXXX0 is
  335.    a file, and the memory manager device driver is not present. If your
  336.    application requires the memory manager, the user will have to reboot the
  337.    system with a disk containing the memory manager and the appropriate
  338.    CONFIG.SYS file before proceeding.
  339.     If bit 7 contains a one, then EMMXXXX0 is a device. Go to Step 10.
  340.  
  341. 10) Issue an "I/O Control for Devices" command (DOS function 44h) with a "get
  342.     output status" command (register AL = 7). You must use the file handle you
  343.     obtained in Step 1 to access the "EMM" device (register BX). Go to Step 11.
  344.  
  345. 11) If the expanded memory device driver is ready, the memory manager passes
  346.     a status value of 0FFh in register AL. The status value is 00h if the device
  347.     driver is not ready.
  348.      If the memory manager device driver is "not ready" and your application
  349.     requires its presence, the user will have to reboot the system with a disk
  350.     containing the memory manager and the appropriate CONFIG.SYS file before
  351.     proceeding.
  352.      If the memory manager device driver is "ready," go to Step 12.
  353.  
  354. 12) Issue a "Close File Handle" command (DOS function 3Eh) to close the expanded
  355.     memory device driver. You must use the file handle you obtained in Step 1 to
  356.     close the "EMM" device (register BX).
  357.  
  358.  
  359.  
  360.  The "Get Interrupt Vector" technique
  361.  
  362.  Any type of program can use this method to test for the presence of the EMM.
  363.  
  364.  Use this method (not the "Open Handle" method) if your program is a device
  365. driver or if it interrupts DOS during file system operations.
  366.  
  367.  Follow these steps in order:
  368.  
  369. 1) Issue a "get vector" command (DOS function 35h) to obtain the contents of
  370.    interrupt vector array entry number 67h (addresses 0000:019Ch thru
  371.    0000:019Fh).
  372.     The memory manager uses this interrupt vector to perform all manager
  373.    functions. The offset portion of this interrupt service routine address is
  374.    stored in the word located at address 0000:019Ch; the segment portion is
  375.    stored in the word located at address 0000:019Eh.
  376. 2) Compare the "device name field" with the contents of the ASCII string which
  377.    starts at the address specified by the segment portion of the contents of
  378.    interrupt vector address 67h and a fixed offset of 000Ah. If DOS loaded the
  379.    memory manager at boot time this name field will have the name of the device
  380.    in it.
  381.     Since the memory manager is implemented as a character device driver, its
  382.    program origin is 0000h. Device drivers are required to have a "device
  383.    header" located at the program origin. Within the "device header" is an 8
  384.    byte "device name field." For a character mode device driver this name field
  385.    is always located at offset 000Ah within the device header. The device name
  386.    field contains the name of the device which DOS uses when it references the
  387.    device.
  388.     If the result of the "string compare" in this technique is positive, the
  389.    memory manager is present.
  390.  
  391.  
  392.  
  393.  Terminate and Stay Resident (TSR) Program Cooperation:
  394.  In order for TSR's to cooperate with each other and with other applications,
  395. TSRs must follow this rule: a program may only remap the DOS partition it lives
  396. in. This rule applies at all times, even when no expanded memory is present.
  397.  
  398.  
  399.  
  400.  
  401. EXPANDED MEMORY SERVICES
  402.  
  403. FUNCTIONS DEFINED IN EMS 3.2 SPECIFICATION
  404.  
  405. Interrupt 67h
  406.  
  407. Function 40h Get Manager Status
  408. LIM Function Call 1
  409.              Returns a status code indicating whether the memory manager is
  410.              present and the hardware is working correctly.
  411. entry   AH      40h
  412. return  AH      error status: 00h, 80h, 81h, 84h
  413. note 1) upward and downward compatible with both EMS and EEMS 3.2.
  414.         this call can be used only after establishing that the EMS driver is in
  415.         fact present
  416.      2) uses register AX
  417.  
  418.  
  419. Function 41h Get Page Frame Segment
  420. LIM Function Call 2
  421.              Obtain segment address of the page frame used by the EMM.
  422. entry   AH      41h
  423. return  AH      error status: 00h, 80h, 81h, 84h
  424.         BX      page frame segment address (error code 0)
  425. note 1) upward and downward compatible with both EMS and EEMS 3.2.
  426.      2) uses registers AX & BX
  427.  
  428.  
  429. Function 42h Get Unallocated Page Count
  430. LIM Function Call 3
  431.              Obtain total number of logical expanded memory pages present in
  432.              the system and the number of those pages not already allocated.
  433. entry   AH      42h
  434. return  AH      error status: 00h, 80h, 81h, 84h
  435.         BX      number of unallocated pages currently availible
  436.         DX      total number of pages
  437. note 1) upward and downward compatible with both EMS and EEMS 3.2. Note that EMS
  438.         and EEMS 3.2 had no mechanism to return the maximum number of handles
  439.         that can be allocated by programs. This is handled by the EMS 4.0 new
  440.         function 54h/02h.
  441.      2) uses registers AX, BX, DX
  442.  
  443.  
  444. Function 43h Get Handle and Allocate Memory
  445. LIM Function Call 4
  446.              Notifies the EMM that a program will be using extended memory,
  447.              obtains a handle, and allocates a certain number of logical pages
  448.              of extended memory to be controlled by that handle
  449. entry   AH      43h
  450.         BX      number of 16k logical pages requested (zero OK)
  451. return  AH      error status: 00h, 80h, 81h, 84h, 85h, 87h, 88h, 89h
  452.         DX      unique EMM handle (see note 2)
  453. note 1) upward compatible with both EMS and EEMS 3.2; EMS and EEMS 3.2 do not
  454.         allow the allocation of zero pages (returns error status 89h). EMS 4.0
  455.         does allow zero pages to be requested for a handle, allocating pages
  456.         later using function 51h
  457.      2) your program must use this EMM handle as a parameter in any function
  458.         that requires it. You can use up to 255 handles. The uppermost byte of
  459.         the handle will be zero and cannot be used by the application.
  460.      3) regs AX & DX are used
  461.  
  462.  
  463. Function 44h Map Memory
  464. LIM Function Call 5
  465.              Maps one of the logical pages of expanded memory assigned to a
  466.              handle onto one of the four physical pages within the EMM's page
  467.              frame.
  468. entry   AH      44h
  469.         AL      physical page to be mapped (0-3)
  470.         BX      the logical page to be mapped (zero through [number of pages
  471.                 allocated to the EMM handle - 1]). If the logical page number
  472.                 is 0FFFFh, the physical page specified in AL will be unmapped
  473.                 (made inaccessible for reading or writing).
  474.         DX      the EMM handle your program received from Function 4 (Allocate
  475.                 Pages).
  476. return  AH      error status: 00h, 80h, 81h, 83h, 84h, 8Ah, 8Bh
  477. note 1) downward compatible with both EMS and EEMS 3.2; EMS and EEMS 3.2 do not
  478.         support unmap (logical page 0FFFFh) capability. Also, EEMS 3.2
  479.         specified there were precisely four physical pages; EMS 4.0 uses the
  480.         subfunctions of function 58h to return the permitted number of physical
  481.         pages. This incorporates the functionality of function 69h ("function
  482.         42") of EEMS.
  483.      2) uses register AX
  484.  
  485.  
  486. Function 45h Release Handle and Memory
  487. LIM Function Call 6
  488.              Deallocates the logical pages of expanded memory currently
  489.              assigned to a handle and then releases the handle itself.
  490. entry   AH      45h
  491.         DX      handle
  492. return  AH      error status: 00h, 80h, 81h, 83h, 84h, 86h
  493. note 1) upward and downward compatible with both EMS and EEMS 3.2.
  494.      2) uses register AX
  495.      3) when a handle is deallocated, its name is set to all ASCII nulls
  496.         (binary zeros).
  497.      4) a program must perform this function before it exits to DOS or no other
  498.         programs can use these pages or the EMM handle.
  499.  
  500.  
  501. Function 46h Get EMM Version
  502. LIM Function Call 7
  503.              Returns the version number of the Expanded Memory Manager software.
  504. entry   AH      46h
  505. return  AH      error status: 00h, 80h, 81h, 84h
  506.         AL      version number byte (if AL=00h)
  507.                 binary coded decimal (BCD) format if version byte:
  508.                 high nibble: integer digit of the version number
  509.                 low nibble : fractional digit of version number
  510.                 i.e., version 4.0 is represented like this:
  511.                           0100 0000
  512.                             /   \
  513.                            4  .  0
  514. note 1) upward and downward compatible with both EMS and EEMS 3.2. It appears
  515.         that the intended use for this function is to return the version of the
  516.         vendor implementation of the expanded memory manager instead of the
  517.         specification version.
  518.      2) uses register AX
  519.  
  520.  
  521. Function 47h Save Mapping Context
  522. LIM Function Call 8
  523.              Save the contents of the expanded memory page-mapping registers on
  524.              the expanded memory boards, associating those contents with a
  525.              specific EMM handle.
  526. entry   AH      47h
  527.         DX      caller's EMM handle (NOT current EMM handle)
  528. return  AH      error status:  00h, 80h, 81h, 83h, 84h, 8Ch, 8Dh
  529. note 1) upward and downward compatible with both EMS and EEMS 3.2.
  530.      2) This only saves the context saved in EMS 3.2 specification; if a driver,
  531.         interrupt routine or TSR needs to do more, functions 4Eh (Page Map
  532.         functions) or 4Fh (Partial Page Map functions) should be used.
  533.      3) no mention is made about the number of save contexts to provide. AST
  534.         recommends in their Rampage AT manual one save context for each handle
  535.         plus one per possible interrupt (5 + <handles>).
  536.      4) uses register AX
  537.      5) this function saves the state of the map registers for only the 64K page
  538.         frame defined in versions 3.x of the LIM. Since all applications written
  539.         to LIM versions 3.x require saving the map register state of only this
  540.         64K page frame, saving the entire mapping state for a large number of
  541.         mappable pages would be inefficient use of memory. Applications that use
  542.         a mappable memory region outside the LIM 3.x page frame should use
  543.         functions 15 or 16 to save and restore the state of the map registers.
  544.  
  545.  
  546. Function 48h Restore Page Map
  547. LIM Function Call 9
  548.              Restores the contents of all expanded memory hardwere page-mapping
  549.              registers to the values associated with the given handle by a
  550.              previous function 08h (Save Mapping Context).
  551. entry   AH      48h
  552.         DX      caller's EMM handle (NOT current EMM handle)
  553. return  AH      error status: 00h, 80h, 81h, 83h, 84h, 8Eh
  554. note 1) upward and downward compatible with both EMS and EEMS 3.2.
  555.      2) This only restores the context saved in EMS 3.2 specification; if a
  556.         driver, interrupt routine or TSR needs to do more, functions 4Eh (Page
  557.         Map functions) or 4Fh (Partial Page Map functions) should be used.
  558.      3) uses register AX
  559.      4) this function saves the state of the map registers for only the 64K page
  560.         frame defined in versions 3.x of the LIM. Since all applications written
  561.         to LIM versions 3.x require saving the map register state of only this
  562.         64K page frame, saving the entire mapping state for a large number of
  563.         mappable pages would be inefficient use of memory. Applications that use
  564.         a mappable memory region outside the LIM 3.x page frame should use
  565.         functions 15 or 16 to save and restore the state of the map registers.
  566.  
  567.  
  568. Function 49h Reserved
  569. LIM Function Call 10
  570.              This function was used in EMS 3.0, but was no longer documented in
  571.              EMS 3.2. It formerly returned the page mapping register I/O port
  572.              array. Use of this function is discouraged, and in EMS 4.0 may
  573.              conflict with the use of the new functions 16 through 30 (4Fh
  574.              through 5Dh) and functions 10 and 11. Functions 10 and 11 are
  575.              specific to the hardware on Intel expanded memory boards and may
  576.              not work correctly on all vendors' expanded memory boards.
  577.  
  578.  
  579. Function 4Ah Reserved
  580. LIM Function Call 11
  581.              This function was used in EMS 3.0, but was no longer documented in
  582.              EMS 3.2. It was formerly Get Page Translation Array. Use of this
  583.              function is discouraged, and in EMS 4.0 may conflict with the use
  584.              of the new functions (4Fh through 5Dh).
  585.  
  586.  
  587. Function 4Bh Get Number of EMM Handles
  588. LIM Function Call 12
  589.              The Get Handle Count function returns the number of open EMM
  590.              handles (including the operating system handle 0) in the system.
  591. entry   AH      4Bh
  592. return  AH      error status: 00h, 80h, 81h, 84h
  593.         BX      handle count (AH=00h) (including the operating system handle
  594.                 [0]). max 255.
  595. note 1) upward and downward compatible with EMS and EEMS 3.2.
  596.      2) uses registers AX and BX
  597.  
  598.  
  599. Function 4Ch Get Pages Owned by Handle
  600. LIM Function Call 13
  601.              Returns number of logical expanded memory pages allocated to a
  602.              specific EMM handle.
  603. entry   AH      4Ch
  604.         DX      handle
  605. return  AH      error status: 00h, 80h, 81h, 83h, 84h
  606.         BX      pages allocated to handle, max 2048 because the EMM allows a
  607.                 maximum of 2048 pages (32M bytes) of expanded memory.
  608. note 1) This function is upward compatible with EMS and EEMS 3.2.
  609.      2) programmers should compare the number returned in BX with the maximum
  610.         number of pages returned by function 42h register DX, total number of
  611.         EMM pages. This should be an UNSIGNED comparison, just in case the spec
  612.         writers decide to use 16 bit unsigned numbers (for a maximum space of
  613.         one gigabyte) instead of signed numbers (for a maximum space of 512
  614.         megabytes). Unsigned comparisons will work properly in either case
  615.      3) uses registers AX and BX
  616.  
  617.  
  618. Function 4Dh Get Pages for All Handles
  619. LIM Function Call 14
  620.              Returns an array containing all active handles and the number of
  621.              logical expanded memory pages associated with each handle.
  622. entry   AH      4Dh
  623.         ES:DI   pointer to 1020 byte array to receive information on an array of
  624.                 structures where a copy of all open EMM handles and the number
  625.                 of pages allocated to each will be stored.
  626. return  AH      error status: 00h, 80h, 81h, 84h
  627.         BX      number of active handles (1-255); array filled with 2-word
  628.                 entries, consisting of a handle and the number of pages
  629.                 allocated to that handle. (including the operating system handle
  630.                 [0]). BX cannot be zero because the operating system handle is
  631.                 always active and cannot be deallocated.
  632. note 1) NOT COMPATIBLE with EMS or EEMS 3.2, since the new special OS handle
  633.         0000h is returned as part of the array. Unless benign use of this
  634.         information is used (such as displaying the handle and count of pages
  635.         associated with the handle) code should be changed to only work with
  636.         handles between 01h and FFh and to specifically ignore handle 00h.
  637.      2) The array consists of an array of 255 elements. The first word of each
  638.         element is the handle number, the second word contains the number of
  639.         pages allocated.
  640.      3) There are two types of handles, "standard" and "raw". The specification
  641.         does not talk about how this function works when both raw and standard
  642.         handles exist in a given system. There is no currently known way to
  643.         differentiate between a standard handle and a raw handle in EMS 4.0.
  644.      4) uses registers AX and BX
  645.  
  646.  
  647. Function 4Eh Get or Set Page Map
  648. LIM Function Call 15
  649.              Gets or sets the contents of the EMS page-mapping registers on the
  650.              expanded memory boards.
  651.               This group of four subfunctions is provided for context switching
  652.              required by operating environments and systems. These functions are
  653.              upward and downward compatible with both EMS and EEMS 3.2; in
  654.              addition, these functions now include the functionality of EEMS
  655.              function 6Ah ("function 43") involving all pages.
  656.               The size and contents of the map register array will vary from
  657.              system to system based on hardware vendor, software vendor, number
  658.              of boards and the capacity of each board in the system. Note the
  659.              array size can be determined by function 4Eh/03h.
  660.               Use these functions (except for 03h) instead of Functions 8 and 9
  661.              if you need to save or restore the mapping context but don't want
  662.              (or have) to use a handle.
  663.  
  664.         00h  Get Page Map
  665.              This call saves the mapping context for all mappable memory regions
  666.              (conventional and expanded) by copying the contents of the mapping
  667.              registers from each expanded memory board to a destination array.
  668.              The application must pass a pointer to the destination array.
  669. entry   AH      4Eh
  670.         AL      00h
  671.         ES:DI   pointer to target array
  672. return  AH      error status: 00h, 80h, 81h, 84h, 8Fh
  673. note 1) uses register AX
  674.      2) does not use an EMM handle
  675.  
  676.  
  677.          01h  Set Page Map
  678.              This call the mapping context for all mappable memory regions
  679.              (conventional and expanded) by copying the contents of a source
  680.              array into the mapping registers on each expanded memory board in
  681.              the system. The application must pass a pointer to the source array.
  682. entry   AH      4Eh
  683.         AL      01h
  684.         DS:SI   pointer to source array
  685. return  AH      error status: 00h, 80h, 81h, 84h, 8Fh, 0A3h
  686. note 1) uses register AX
  687.      2) does not use an EMM handle
  688.  
  689.  
  690.         02h  Get & Set Page Map
  691.              This call simultaneously saves the current mapping context and
  692.              restores a previous mapping context for all mappable memory regions
  693.              (both conventional and expanded). It first copies the contents of
  694.              the mapping registers from each expanded memory board in the system
  695.              into a destination array. Then the subfunction copies the contents
  696.              of a source array into the mapping registers on each of the
  697.              expanded memory boards.
  698. entry   AH      4Eh
  699.         AL      02h
  700.         DS:SI   pointer to source array
  701.         ES:DI   pointer to target array
  702. return  AH      error status: 00h, 80h, 81h, 84h, 8Fh, 0A3h
  703. note 1) uses register AX
  704.  
  705.  
  706.           03h  Get Size of Page Map Save Array
  707. entry   AH      4Eh
  708.         AL      03h
  709. return  AH      error status:  00h, 80h, 81h, 84h, 8Fh
  710.         AL      size in bytes of array
  711. note 1) this subfunction does not require an EMM handle
  712.      2) uses register AX
  713.  
  714.  
  715.  
  716. FUNCTIONS NEW TO EMS 4.0
  717.  
  718. Function 4Eh Get or Set Page Map
  719. LIM Function Call 16
  720. entry   AH      4Eh
  721.         AL      00h     if getting mapping registers
  722.                 01h     if setting mapping registers
  723.                 02h     if getting and setting mapping registers at once
  724.                 03h     if getting size of page-mapping array
  725.         DS:SI   pointer to array holding information (AL=01/02)
  726.         ES:DI   pointer to array to receive information (AL=00/02)
  727. return  AH      error status: 00h, 80h, 81h, 84h, 8Fh, 0A3h
  728. note 1) this function was designed to be used by multitasking operating systems
  729.         and should not ordinarily be used by appplication software.
  730.  
  731.  
  732. Function 4Fh Get/Set Partial Page Map
  733. LIM Function Call 16
  734.              These four subfunctions are provided for context switching required
  735.              by interrupt routines, operating environments and systems. This set
  736.              of functions provides extended functionality over the EEMS function
  737.              6Ah (function 43) involving subsets of pages. In EEMS, a subset of
  738.              pages could be specified by starting position and number of pages;
  739.              in this function a list of pages is specified, which need not be
  740.              contiguous.
  741.               Interrupt routines can use this function in place of functions 47h
  742.              and 48h, especially if the interrupt routine wants to use more than
  743.              the standard four physical pages.
  744.         AH      4Fh
  745.         AL      subfunction
  746.                 00h     get partial page map
  747.                         DS:SI   pointer to structure containing list of
  748.                                 segments whose mapping contexts are to be saved
  749.                         ES:DI   pointer to array to receive page map
  750.                 01h     set partial page map
  751.                         DS:SI   pointer to structure containing saved partial
  752.                                 page map
  753.                 02h     get size of partial page map
  754.                         BX      number of mappable segments in the partial map
  755.                                 to be saved
  756. return  AH      error status (00h): 00h, 80h, 81h, 84h, 8Bh, 8Fh, 0A3h
  757.                 error status (01h): 00h, 80h, 81h, 84h, 8Fh, 0A3h
  758.                 error status (02h): 00h, 80h, 81h, 84h, 8Bh, 8Fh
  759.         AL      size of partial page map for subfunction 02h
  760.         DS:SI   (call 00h) pointer to array containing the partial mapping
  761.                 context and any additional information necessary to restore this
  762.                 context to its original state when the program invokes a Set
  763.                 subfunction.
  764. note    uses register AX
  765.  
  766.  
  767. Function 50h Map/Unmap Multiple Pages
  768. LIM Function Call 17
  769. entry   AH      50h
  770.         AL      00h     (by physical page)
  771.                 01h     (by segment number)
  772.         CX      contains the number of entries in the array. For example, if the
  773.                 array contained four pages to map or unmap, then CX would
  774.                 contain 4.
  775.         DX      handle
  776.         DS:SI   pointer to an array of structures that contains the information
  777.                 necessary to map the desired pages.
  778. return  AH      error status: 00h, 80h, 81h, 83h, 84h, 8Ah, 8Bh, 8Fh
  779. note 1) New function permits multiple logical-to-physical assignments to be made
  780.         in a single call.(faster than mapping individual pages)
  781.      2) The source map array is an array of word pairs. The first word of a
  782.         pair contains the logical page to map (0FFFFh if the physical page is
  783.         to be totally unmapped) and the second word of a pair contains the
  784.         physical page number (subfunction 00h) or the segment selector
  785.         (subfunction 01h) of the physical page in which the logical page shall
  786.         be mapped.
  787.      3) A map of available physical pages (by physical page number and segment
  788.         selectors) can be obtained using function 58h/00h, Get Mappable
  789.         Physical Address Array.
  790.      4) uses register AX
  791.      5) Both mapping and unmapping pages can be done simultaneously.
  792.      6) If a request to map or unmap zero pages is made, nothing is done and no
  793.         error is returned.
  794.      7) Pages can be mapped or unmapped using one of two methods. Both methods
  795.         produce identical results.
  796.          A) A logical page and a physical page at which the logical page is to
  797.             be mapped. This method is an extension of Function 5 (Map Handle
  798.             Page).
  799.          B) Specifys both a logical page and a corresponding segment address at
  800.             which the logical page is to be mapped. While functionally the same
  801.             as the first method, it may be easier to use the actual segment
  802.             address of a physical page than to use a number which only
  803.             represents its location. The memory manager verifies whether the
  804.             specified segment address falls on the boundary of a mappable
  805.             physical page. The manager then translates the segment address
  806.             passed to it into the necessary internal representation to map the
  807.             pages.
  808.  
  809.  
  810. Function 51h Reallocate pages
  811. LIM Function Call 18
  812.              This function allows an application to change the number of logical
  813.              pages allocated to an EMM handle.
  814. entry   AH      51h
  815.         BX      number of pages desired at return
  816.         DX      handle
  817. return  AH      error status: 00h, 80h, 81h, 83h, 84h, 87h, 88h
  818.         BX      number of pages now associated with handle
  819. note 1) uses registers AX, BX
  820.      2) Logical pages which were originally allocated with Function 4 are called
  821.         pages and are 16K bytes long. Logical pages which were allocated with
  822.         Function 27 are called raw pages and might not be the same size as pages
  823.         allocated with Function 4.
  824.      3) If the status returned in BX is not zero, the value in BX is equal to
  825.         the number of pages allocated to the handle prior to calling this
  826.         function. This information can be used to verify that the request
  827.         generated the expected results.
  828.  
  829.  
  830. Function 52h Get/Set Handle Attributes
  831. LIM Function Call 19
  832. entry   AH      52h
  833.         AL      subfunction
  834.                 00h     get handle attributes
  835.                 01h     set handle attributes
  836.                         BL      new attribute
  837.                                 00h     make handle volatile
  838.                                 01h     make handle non-volatile
  839.                 02h     get attribute capability
  840.         DX      handle
  841. return  AH      error status: (function 00h) 00h, 80h, 81h, 83h, 84h, 8Fh, 91h
  842.                 error status: (function 01h) 00h, 80h, 81h, 83h, 84h, 8Fh, 90h,
  843.                                              91h
  844.                 error status: (function 02h) 00h, 80h, 81h, 84h, 8Fh
  845.         AL      attribute (for subfunction 00h)
  846.                 00h     handle is volatile
  847.                 01h     handle is nonvolatile
  848.         AL      attribute capability (for subfunction 02h)
  849.                 00h     only volatile handles supported
  850.                 01h     both volatile and non-volatile supported
  851. note 1) uses register AX
  852.      2) A volatile handle attribute instructs the memory manager to deallocate
  853.         both the handle and the pages allocated to it after a warm boot. If all
  854.         handles have the volatile attribute (default) at warm boot the handle
  855.         directory will be empty and all expanded memory will be initialized to
  856.         zero immediately after a warm boot.
  857.      3) If the handle's attribute has been set to non-volatile, the handle, its
  858.         name (if it is assigned one), and the contents of the pages allocated to
  859.         the handle are all maintained after a warm boot.
  860.      4) Most PCs disable RAM refresh signals for a considerable period during a
  861.         warm boot. This can corrupt some of the data in memory boards. Non-
  862.         volatile handles should not be used unless it is definitely known that
  863.         the EMS board will retain proper function through a warm boot.
  864.      5) subfunction 02h can be used to determine whether the memory manager can
  865.         support the non-volatile attribute.
  866.      6) Currently the only attribute supported is non-volatile handles and
  867.         pages, indicated by the least significant bit.
  868.  
  869.  
  870. Function 53h Handle Name Functions
  871. LIM Function Call 20
  872.              EMS handles may be named. Each name may be any eight characters.
  873.              At installation, all handles have their name initialized to ASCII
  874.              nulls (binary zeros). There is no restriction on the characters
  875.              which may be used in the handle name (ASCII chars 00h through
  876.              0FFh). A name of eight nulls (zeroes) is special, and indicates a
  877.              handle has no name. Nulls have no special significance, and they
  878.              can appear in the middle of a name. The handle name is 64 bits of
  879.              binary information to the EMM.
  880.               Functions 53h and 54h provide a way of setting and reading the
  881.              names associated with a particular handle. Function 53h manipulates
  882.              names by number.
  883.               When a handle is assigned a name, at least one character in the
  884.              name must be a non-null character in order to distinguish it from
  885.              a handle without a name.
  886.  
  887.         00h  Get Handle Name
  888.              This subfunction gets the eight character name currently
  889.              assigned to a handle.
  890.               The handle name is initialized to ASCII nulls (binary zeros)
  891.              three times:  when the memory manager is installed, when a handle
  892.              is allocated, and when a handle is deallocated.
  893. entry   AH      53h
  894.         AL      00h
  895.         DX      handle
  896.         ES:DI   pointer to 8-byte handle name array into which the name
  897.                 currently assigned to the handle will be copied.
  898. return  AH      error status: 00h, 80h, 81h, 83h, 84h, 8Fh
  899. note    uses register AX
  900.  
  901.         01h  Set Handle Name
  902.              This subfunction assigns an eight character name to a handle.
  903.              A handle can be renamed at any time by setting the handle's
  904.              name to a new value. When a handle is deallocated, its name is
  905.              removed (set to ASCII nulls).
  906. entry   AH      53h
  907.         AL      01h
  908.         DX      handle
  909.         DS:SI   pointer to 8-byte handle name array that is to be assigned to
  910.                 the handle. The handle name must be padded with nulls if the
  911.                 name is less than eight characters long.
  912. return  AH      error status: 00h, 80h, 81h, 83h, 84h, 8Fh, 0A1h
  913. note    uses register AX
  914.  
  915.  
  916. Function 54h Handle Directory Functions
  917. LIM Function Call 21
  918.              Function 54h manipulates handles by name.
  919.  
  920.         00h  Get Handle Directory
  921.              Returns an array which contains all active handles and the names
  922.              associated with each.
  923. entry   AH      54h
  924.         AL      00h
  925.         ES:DI   pointer to 2550 byte target array
  926. return  AH      error status: 00h, 80h, 81h, 84h, 8Fh
  927.         AL      number of active handles
  928. note 1) The name array consists of 10 byte entries; each entry has a word
  929.         containing the handle number, followed by the eight byte (64 bit) name.
  930.      2) uses register AX
  931.      3) The number of bytes required by the target array is:
  932.                 10 bytes * total number of handles
  933.      4) The maximum size of this array is:
  934.                 (10 bytes/entry) * 255 entries = 2550 bytes.
  935.  
  936.         01h  Search for Named Handle
  937.              Searches the handle name directory for a handle with a particular
  938.              name. If the named handle is found, this subfunction returns the
  939.              handle number associated with the name.
  940. entry   AH      54h
  941.         AL      01h
  942.         DS:SI   pointer to an 8-byte string that contains the name of the
  943.                 handle being searched for
  944. return  AH      error status: 00h, 80h, 81h, 84h, 8Fh, A0h, 0A1h
  945.         DX      handle number
  946. note 1) uses registers AX and DX
  947.  
  948.         02h  Get Total Handles
  949.              Returns the total number of handles the EMM supports, including
  950.              the operating system handle (handle value 0).
  951. entry   AH      54h
  952.         AL      02h
  953. return  AH      error status: 00h, 80h, 81h, 84h, 8Fh
  954.         BX      total number of handles availible
  955. note 1) This is NOT the current number of handles defined, but the maximum
  956.         number of handles that can be supported in the current environment.
  957.      2) uses registers AX and BX
  958.  
  959.  
  960. Function 55h Alter Page Map and Jump (cross page branch)
  961. LIM Function Call 22
  962.              Alters the memory mapping context and transfers control to the
  963.              specified address. Analogous to the FAR JUMP in the 8086 family
  964.              architecture. The memory mapping context which existed before
  965.              calling function is lost.
  966. entry   AH      55h
  967.         AL      00h     physical page numbers provided by caller
  968.                 01h     segment addresses provided by caller
  969.         DX      handle
  970.         DS:SI   pointer to structure containing map and jump address
  971. return  AH      error status: 00h, 80h, 81h, 83h, 84h, 8Ah, 8Bh, 8Fh
  972. note 1) Flags and all registers except AX are preserved across the jump.
  973.      2) uses register AX
  974.      3) Values in registers which don't contain required parameters maintain the
  975.         values across the jump. The values in registers (with the exception of
  976.         AX) and the flag state at the beginning of the function are still in the
  977.         registers and flags when the target address is reached.
  978.      4) Mapping no pages and jumping is not considered an error. If a request to
  979.         map zero pages and jump is made, control is transferred to the target
  980.         address, and this function performs a far jump.
  981.  
  982.  
  983. Function 56h Alter Page Map and Call (cross page call)
  984. LIM Function Call 23
  985.         00h and 01h
  986.                This subfunction saves the current memory mapping context,
  987.                alters the specified memory mapping context, and transfers
  988.                control to the specified address.
  989. entry   AH      56h
  990.         AL      00h physical page numbers provided by caller
  991.                 01h segment addresses provided by caller
  992.         DS:SI   pointer to structure containing page map and call address
  993.         DX      handle
  994. return  AH      error status: 00h, 80h, 81h, 83h, 84h, 8Ah, 8Bh, 8Fh
  995. note 1) Flags and all registers except AX are preserved to the called routine.
  996.         On return, flags and all registers except AX are preserved; AL is set to
  997.         zero and AX is undefined.
  998.      2) uses register AX
  999.      3) Values in registers which don't contain required parameters maintain
  1000.         the values across the call. The values in registers (with the exception
  1001.         of AX) and the flag state at the beginning of the function are still in
  1002.         the registers and flags when the target address is reached.
  1003.      4) Developers using this subfunction must make allowances for the
  1004.         additional stack space this subfunction will use.
  1005.  
  1006.         02h  Get Page Map Stack Space Size
  1007.              Since the Alter Page Map & Call function pushes additional
  1008.              information onto the stack, this subfunction returns the number of
  1009.              bytes of stack space the function requires.
  1010. entry   AH      56h
  1011.         AL      02h
  1012. return: BX      number of bytes of stack used per call
  1013.         AH      error status: 00h, 80h, 81h, 84h, 8Fh
  1014. note 1) if successful, the target address is called. Use a RETF to return and
  1015.         restore mapping context
  1016.      2) uses registers AX, BX
  1017.  
  1018.  
  1019. Function 57h Move/Exchange Memory Region
  1020. LIM Function Call 24
  1021.         00h  Move Memory Region
  1022.              Moves data between two memory areas. Includes moves between paged
  1023.              and non-paged areas, or between two different paged areas.
  1024. entry   AH      57h
  1025.         AL      00h
  1026.         SI      offset to request block
  1027.         DS      segment selector to request block
  1028. return  AH      error status: 00h, 80h, 81h, 83h, 84h, 8Ah, 8Fh, 92h, 93h, 94h,
  1029.                 95h, 96h, 98h, 0A2h
  1030. note 1) uses register AX
  1031.  
  1032.         01h  Exchange Memory Region
  1033.              Exchanges data between two memory areas. Includes exchanges between
  1034.              paged and non-paged areas, or between two different paged areas.
  1035. entry   AH      57h
  1036.         AL      01h
  1037.         DS:SI   pointer to the data structure which contains the source and
  1038.                 destination information for the exchange.
  1039. return  AH      error status: 00h, 80h, 81h, 83h, 84h, 8Ah, 8Fh, 93h, 94h, 95h,
  1040.                 96h, 97h, 98h, 0A2h
  1041. note 1) The request block is a structure with the following format:
  1042.         dword   region length in bytes
  1043.         byte    0=source in conventional memory
  1044.                 1=source in expanded memory
  1045.         word    source handle
  1046.         word    source offset in page or selector
  1047.         word    source logical page (expanded) or selector (conventional)
  1048.         byte    0=target in conventional memory
  1049.                 1=target in expanded memory
  1050.         word    target handle
  1051.         word    target offset in page or selector
  1052.         word    target logical page (expanded) or selector (conventional)
  1053.      2) Expanded memory allocated to a handle is considered to be a linear
  1054.         array, starting from logical page 0 and progressing through logical page
  1055.         1, 2, ... n, n+1, ... up to the last logical page in the handle.
  1056.      3) uses register AX
  1057.  
  1058.  
  1059. Function 58h Mappable Physical Address Array
  1060. LIM Function Call 25
  1061.              These functions let you obtain a complete map of the way physical
  1062.              memory is laid out in a vendor independent manner. This is a
  1063.              functional equivalent of EEMS function 68h ("function 41"). EEMS
  1064.              function 60h ("function 33") is a subset call of 68h.
  1065.  
  1066.         00h  Get Array
  1067.              Returns an array containing the segment address and physical page
  1068.              number for each mappable physical page in a system. This array
  1069.              provides a cross reference between physical page numbers and the
  1070.              actual segment addresses for each mappable page in the system.
  1071. entry   AH      58h
  1072.         AL      00h
  1073.         ES:DI   pointer to target array
  1074. return  AH      error status: 00h, 80h, 81h, 84h, 8Fh
  1075.         CX      entries in target array
  1076. note 1) The information returned is in an array composed of word pairs. The
  1077.         first word is the physical page's segment selector, the second word the
  1078.         physical page number. Note that values are not necessarily returned in a
  1079.         particular order, either ascending/decending segment selector values or
  1080.         as ascending/decending physical page number.
  1081.      2) For compatibility with earlier EMS specifications, physical page zero
  1082.         contains the segment selector value returned by function 41h, and
  1083.         physical pages 1, 2 and 3 return segment selector values that corrospond
  1084.         to the physical 16 KB blocks immediately following physical page zero.
  1085.      3) uses registers AX and CX
  1086.      4) The array is sorted in ascending segment order. This does not mean that
  1087.         the physical page numbers associated with the segment addresses are
  1088.         also in ascending order.
  1089.  
  1090.         01h   Get Physical Page Address Array Entries.
  1091.               Returns a word which represents the number of entries in the
  1092.               array returned by the previous subfunction. This number also
  1093.               indicates the number of mappable physical pages in a system.
  1094. entry   AH      58h
  1095.         AL      01h
  1096. return  AH      error status: 00h, 80h, 81h, 84h, 8Fh
  1097.         CX      number of entries returned by 58h/00h
  1098. note 1) multiply CX by 4 for the byte count.
  1099.      2) uses registers AX and CX
  1100.  
  1101.  
  1102. Function 59h Get Expanded Memory Hardware Information
  1103. LIM Function Call 26
  1104.              These functions return information specific to a given hardware
  1105.              implementation and to use of raw pages as opposed to standard
  1106.              pages. The intent is that only operating system code ever need use
  1107.              these functions.
  1108.         00h  Get EMS Hardware Info
  1109.              Returns an array containing expanded memory hardware configuration
  1110.              information for use by an operating system.
  1111. entry   AH      59h
  1112.         AL      00h
  1113.         ES:DI   pointer to 10 byte target array
  1114.                 The target array has the following format:
  1115.                 word: raw page size in paragraphs (multiples of 16 bytes)
  1116.                 word: number of alternate register sets
  1117.                 word: size of page maps (function 4Eh [15])
  1118.                 word: number of alternate registers sets for DMA
  1119.                 word: DMA operation -- see full specification
  1120. return  AH      error status: 00h, 80h, 81h, 84h, 8Fh, 0A4h
  1121. note 1) uses register AX
  1122.      2) This function is for use by operating systems only.
  1123.      3) This function can be disabled at any time by the operating system.
  1124.  
  1125.         01h  Get Unallocated Raw Page Count
  1126.              Returns the number of unallocated non-standard length mappable
  1127.              pages as well as the total number of non-standard length mappable
  1128.              pages of expanded memory
  1129. entry   AH      59h
  1130.         AL      01h
  1131. return  AH      error status: 00h, 80h, 81h, 84h, 8Fh
  1132.         BX      unallocated raw pages availible for use
  1133.         DX      total raw 16k pages of expanded memory
  1134. note 1) uses registers AX, BX, CX
  1135.      2) An expanded memory page which is a sub-multiple of 16K is termed a raw
  1136.         page. An operating system may deal with mappable physical page sizes
  1137.         which are sub-multiples of 16K bytes.
  1138.      3) If the expanded memory board supplies pages in exact multiples of 16K
  1139.         bytes, the number of pages this function returns is identical to the
  1140.         number Function 3 (Get Unallocated Page Count) returns. In this case,
  1141.         there is no difference between a page and a raw page.
  1142.  
  1143.  
  1144. Function 5Ah Allocate Raw Pages
  1145. LIM Function Call 27
  1146.              Allocates the number of nonstandard size pages that the operating
  1147.              system requests and assigns a unique EMM handle to these pages.
  1148. entry   AH      5Ah
  1149.         AL      00h     allocate standard pages
  1150.                 01h     allocate raw pages
  1151.         BX      number of pages to allocate
  1152. return  AH      error status: 00h, 80h, 81h, 84h, 85h, 87h, 88h
  1153.         DX      unique raw EMM handle (1-255)
  1154. note 1) it is intended this call be used only by operating systems
  1155.      2) uses registers AX and DX
  1156.      3) For all functions using the raw handle returned in DX, the length of
  1157.         the physical and logical pages allocated to it are some nonstandard
  1158.         length (that is, not 16K bytes).
  1159.      4) this call is primarily for use by operating systems or EMM drivers
  1160.         supporting hardware with a nonstandard EMS page size.
  1161.  
  1162.  
  1163. Function 5Bh Alternate Map Register Set - DMA Registers
  1164. LIM Function Call 28
  1165. entry   AH      00h     Get Alternate Map Register Set
  1166.                 01h     Set Alternate Map Register Set
  1167.                         BL      new alternate map register set number
  1168.                         ES:DI   pointer to map register context save area if
  1169.                                 BL=0
  1170.                 02h     Get Alternate Map Save Array Size
  1171.                 03h     Allocate Alternate Map Register Set
  1172.                 04h     Deallocate Alternate Map Register Set
  1173.                         BL      number of alternate map register set
  1174.                 05h     Allocate DMA Register Set
  1175.                 06h     Enable DMA on Alternate Map Register Set
  1176.                         BL      DMA register set number
  1177.                         DL      DMA channel number
  1178.                 07h     Disable DMA on Alternate Map Register Set
  1179.                         BL      DMA register set number
  1180.                 08h     Deallocate DMA Register Set
  1181.                         BL      DMA register set number
  1182. return  AH      status: 00h, 02h   00h, 80h, 84h, 81h, 8Fh, 0A4h
  1183.                         01h        00h, 80h, 81h, 84h, 8Fh, 9Ah, 9Ch, 9Dh,
  1184.                                    0A3h, 0A4h
  1185.                         03h, 05h   00h  80h  81h  84h, 8Fh, 9Bh, 0A4h
  1186.                         04h        00h, 80h, 81h, 84h, 8Fh, 9Ch, 9Dh, 0A4h
  1187.                         06h, 07h   00h, 80h, 81h, 84h, 8Fh, 9Ah, 9Ch, 9Dh, 9Eh,
  1188.                                    9Fh, 0A4h
  1189.         BL      current active alternate map register set number if nonzero
  1190.                 (AL=0)
  1191.         BL      number of alternate map register set; zero if not supported
  1192.                 (AL=3)
  1193.         DX      array size in bytes (subfunction 02h)
  1194.         ES:DI   pointer to a map register context save area if BL=0 (AL=0)
  1195. note 1) this call is for use by operating systems only, and can be enabled
  1196.         or disabled at any time by the operating system
  1197.      2) This set of functions performs the same functions at EEMS function 6Ah
  1198.         subfunctions 04h and 05h ("function 43").
  1199.      3) 00h uses registers AX, BX, ES:DI
  1200.         01h uses register AX
  1201.         02h uses registers AX and DX
  1202.         03h uses registers AX and BX
  1203.         04h uses register AX
  1204.         05h uses registers AX, BX
  1205.         06h uses register AX
  1206.         07h uses register AX
  1207.  
  1208.  
  1209. Function 5Ch Prepare EMS Hardware for Warm Boot
  1210. LIM Function Call 29
  1211.              Prepares the EMM hardware for a warm boot.
  1212. entry   AH      5Ch
  1213. return  AH      error status: 00h, 80h, 81h, 84h
  1214. note 1) uses register AX
  1215.      2) this function assumes that the next operation that the operating system
  1216.         performs is a warm boot of the system.
  1217.      3) in general, this function will affect the current mapping context, the
  1218.         alternate register set in use, and any other expanded memory hardware
  1219.         dependencies which need to be initialized at boot time.
  1220.      4) if an application decides to map memory below 640K, the application must
  1221.         trap all possible conditions leading to a warm boot and invoke this
  1222.         function before performing the warm boot itself.
  1223.  
  1224.  
  1225. Function 5Dh Enable/Disable OS Function Set Functions
  1226. LIM Function Call 30
  1227.              Lets the OS allow other programs or device drivers to use the OS
  1228.              specific functions. This capability is provided only for an OS
  1229.              which manages regions of mappable conventional memory and cannot
  1230.              permit programs to use any of the functions which affect that
  1231.              memory, but must be able to use these functions itself.
  1232. entry   AH      5Dh
  1233.         AL      00h     enable OS function set
  1234.                 01h     disable OS function set
  1235.                 02h     return access key (resets memory manager, returns access
  1236.                         key at next invocation)
  1237.         BX,CX   access key returned by first invocation
  1238. return  BX,CX   access key, returned only on first invocation of function
  1239.         AH      status  00h, 80h, 81h, 84h, 8Fh, 0A4h
  1240. note 1) this function is for use by operating systems only. The operating system
  1241.         can disable this function at any time.
  1242.      2) 00h uses registers AX, BX, CX
  1243.         01h uses registers AX, BX, CX
  1244.         02h uses register AX
  1245.      3) 00h, 01h: The OS/E (Operating System/Environment) functions these
  1246.         subfunctions affect are:
  1247.         Function 26. Get Expanded Memory Hardware Information.
  1248.         Function 28. Alternate Map Register Sets.
  1249.         Function 30. Enable/Disable Operating System Functions.
  1250.  
  1251.  
  1252. Function 5Eh Unknown
  1253. LIM Function call (not defined under LIM)
  1254.  
  1255.  
  1256. Function 5Fh Unknown
  1257. LIM Function call (not defined under LIM)
  1258.  
  1259.  
  1260. Function 60h EEMS - Get Physical Window Array
  1261. LIM Function call (not defined under LIM)
  1262. entry   AH      60h
  1263.         ES:DI   pointer to buffer
  1264. return  AH      status
  1265.         AL      number of entries
  1266.         buffer at ES:DI filled
  1267.  
  1268.  
  1269. Function 61h Generic Accelerator Card Support
  1270. LIM Function Call 34
  1271.              Contact AST Research for a copy of the Generic Accelerator Card
  1272.              Driver (GACD) Specification
  1273. note    Can be used by accelerator card manufacturer to flush RAM cache,
  1274.         ensuring that the cache accurately reflects what the processor would
  1275.         see without the cache.
  1276.  
  1277.  
  1278. Function 68h EEMS - Get Addresses of All Page Frames in System
  1279. LIM Function Call (not defined under LIM)
  1280. entry   AH      68h
  1281.         ES:DI   pointer to buffer
  1282. return  AH      status
  1283.         AL      number of entries
  1284.         buffer at ES:DI filled
  1285. note    Equivalent to LIM 4.0 function 58h
  1286.  
  1287.  
  1288. Function 69h EEMS - Map Page Into Frame
  1289. LIM Function Call (not defined under LIM)
  1290. entry   AH      69h
  1291.         AL      frame number
  1292.         BX      page number
  1293.         DX      handle
  1294. return  AH      status
  1295. note    Similar to EMS function 44h
  1296.  
  1297.  
  1298. Function 6Ah  EEMS - Page Mapping
  1299. LIM Function Call (not defined under LIM)
  1300. entry   AH      6Ah
  1301.         AL      00h save partial page map
  1302.                         CH      first page frame
  1303.                         CL      number of frames
  1304.                         ES:DI   pointer to buffer which is to be filled
  1305.                 01h restore partial page map
  1306.                         CH      first page frame
  1307.                         CL      number of frames
  1308.                         DI:SI   pointer to previously saved page map
  1309.                 02h save and restore partial page map
  1310.                         CH      first page frame
  1311.                         CL      number of frames
  1312.                         ES:DI   buffer for current page map
  1313.                         DI:SI   new page map
  1314.                 03h get size of save array
  1315.                         CH      first page frame
  1316.                         CL      number of frames
  1317.                 return  AL      size of array in bytes
  1318.                 04h switch to standard map register setting
  1319.                 05h switch to alternate map register setting
  1320.                 06h deallocate pages mapped to frames in conventional memory
  1321.                         CH      first page frame
  1322.                         CL      number of frames
  1323. return  AH      status
  1324. note    Similar to LIM function 4Eh, except that a subrange of pages can
  1325.         be specified
  1326.  
  1327.  
  1328.  
  1329. EXPANDED MEMORY MANAGER ERROR CODES
  1330.  
  1331.  EMM error codes are returned in AH after a call to the EMM (int 67h).
  1332.  
  1333. code    meaning
  1334.  
  1335. 00h     function successful
  1336. 80h     internal error in EMM software (possibly corrupted driver)
  1337. 81h     hardware malfunction
  1338. 82h     EMM busy (dropped in EEMS 3.2)
  1339. 83h     invalid EMM handle
  1340. 84h     function requested not defined - unknown function code in AH.
  1341. 85h     no more EMM handles availible
  1342. 86h     error in save or restore of mapping context
  1343. 87h     more pages requested than exist
  1344. 88h     allocation request specified more logical pages than currently
  1345.         availible in system (request does not exceed actual physical number of
  1346.         pages, but some are already allocated to other handles); no pages
  1347.         allocated
  1348. 89h     zero pages; cannot be allocated (dropped in EMS 4.0)
  1349. 8Ah     logical page requested to be mapped outside range of logical pages
  1350.         assigned to handle
  1351. 8Bh     illegal page number in mapping request (valid numbers are 0 to 3)
  1352. 8Ch     page-mapping hardware state save area full
  1353. 8Dh     save of mapping context failed; save area already contains context
  1354.         associated with page handle
  1355. 8Eh     retore of mapping context failed; save area does not contain context
  1356.         for requested handle
  1357. 8Fh     subfunction parameter not defined (unknown function)
  1358.  
  1359. LIM 4.0 extended error codes:
  1360.  
  1361. 90h     attribute type undefined
  1362. 91h     warm boot data save not implemented
  1363. 92h     move overlaps memory
  1364. 93h     move/exchange larger than allocated region
  1365. 94h     conventional/expanded regions overlap
  1366. 95h     logical page offset outside of logical page
  1367. 96h     region larger than 1 MB
  1368. 97h     exchange source/destination overlap
  1369. 98h     source/destination undefined or not supported
  1370. 99h     (no status assigned)
  1371. 9Ah     alternate map register sets supported, specified set is not
  1372. 9Bh     all alternate map & DMA register sets allocated
  1373. 9Ch     alternate map & DMA register sets not supported
  1374. 9Dh     alternate map register or DMA set not defined, allocated or is currently
  1375.         defined set
  1376. 9Eh     dedicated DMA channels not supported
  1377. 9Fh     dedicated DMA channels supported; specifed channel is not
  1378. 0A0h    named handle could not be found
  1379. 0A1h    handle name already exists
  1380. 0A2h    move/exchange wraps around 1 MB boundry
  1381. 0A3h    data structure contains corrupted data
  1382. 0A4h    access denied
  1383.  
  1384.